package rgbos.forum.persistance;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import rgbos.forum.domain.Auditor;
import rgbos.forum.domain.Topic;

public class XMLTopic extends XMLUtil{
	private String topicFileName_ = "topics.xml";
	private DateFormat dateFormat_;

	public XMLTopic() {
		dateFormat_ =  new SimpleDateFormat("dd/MM/yyyy");
	}

	//topic actions
	public int saveNewTopic(Topic topic){
		Element root = getTopicDoc_().getDocumentElement();
		NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
		for (int i = 0; i < tempNl.getLength(); i++) {
			Node tempNode = tempNl.item(i);
			NamedNodeMap tempNMap = tempNode.getAttributes();
			String id = tempNMap.getNamedItem("ID").getNodeValue();
			if (id.contentEquals(String.valueOf(topic.getId_()))) {
				Auditor.Log("The topic " + topic.getId_() + " was ALLREADY added to the forum.", this.getClass());
				return -1;
			}
		}

		Element nodeTopic = getTopicDoc_().createElement("Topic");
		nodeTopic.setAttribute("ID", String.valueOf(topic.getId_()));
		nodeTopic.setAttribute("title", topic.getTitle_());
		nodeTopic.setAttribute("authorName", topic.getAuthorName());
		nodeTopic.setAttribute("creationDate", dateFormat_.format(topic.getCreationDate_()));
		nodeTopic.setAttribute("postCount", String.valueOf(topic.getPostCount()));
		nodeTopic.setAttribute("viewCount", String.valueOf(topic.getViewCount()));
		//Creating the topic's Posts ID :
		Element postsID = getTopicDoc_().createElement("PostsIDs");
		for (int i=0;i<topic.getPostCount();i++){
			postsID.setAttribute("postID"+i, String.valueOf(topic.getPostVector().get(i)));
		}

		nodeTopic.appendChild(postsID);
		root.appendChild(nodeTopic);

		Auditor.Log("The topic " + topic.getId_() + " was added to the forum.", this.getClass());
		//modify counter :
		int tempCounter = Integer.valueOf(root.getAttribute("Counter"));
		root.setAttribute("Counter",String.valueOf(tempCounter+1));
		// writing the new XML to file
		XMLUtil.writeXMLFile(getTopicDoc_(), topicFileName_);
		//System.exit(1);
		return topic.getId_();
	}
	public boolean modifyTopic(Topic topic){
		try {
			NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
			for (int i = 0; i < tempNl.getLength(); i++) {
				Node tempNode = tempNl.item(i);
				NamedNodeMap tempNMap = tempNode.getAttributes();
				String id = tempNMap.getNamedItem("ID").getNodeValue();
				if (id.contentEquals(String.valueOf(topic.getId_()))) {

					Element newChild = getTopicDoc_().createElement("Topic");
					newChild.setAttribute("ID", String.valueOf(topic.getId_()));
					newChild.setAttribute("title", topic.getTitle_());
					newChild.setAttribute("authorName", String.valueOf(topic.getAuthorName()));
					newChild.setAttribute("creationDate", dateFormat_.format(topic.getCreationDate_()));
					newChild.setAttribute("postCount", String.valueOf(topic.getPostCount()));
					newChild.setAttribute("viewCount", String.valueOf(topic.getViewCount()));
					//Modifying the topic's Posts ID :
					Element newPostsID = getTopicDoc_().createElement("PostsIDs");
					for (int j=0;j<topic.getPostVector().size();j++){
						newPostsID.setAttribute("postID"+j, String.valueOf(topic.getPostVector().get(j)));
					}
					newChild.appendChild(newPostsID);
					tempNode.getParentNode().replaceChild(newChild, tempNode);
					Auditor.Log("The topic " + topic.getId_() + " was modified", this.getClass());
					XMLUtil.writeXMLFile(getTopicDoc_(), topicFileName_);
					return true;
				}
			}

		} catch (DOMException e) {
			return false;
		}
		return false;
	}
	public boolean deleteTopic(int topicId){
		Element root = getTopicDoc_().getDocumentElement();
		try {
			NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
			for (int i = 0; i < tempNl.getLength(); i++) {
				Node tempNode = tempNl.item(i);
				NamedNodeMap tempNMap = tempNode.getAttributes();
				String id = tempNMap.getNamedItem("ID").getNodeValue();
				if (id.contentEquals(String.valueOf(topicId))) {
					tempNode.getParentNode().removeChild(tempNode);

					//modify counter :
					int tempCounter = Integer.valueOf(root.getAttribute("Counter"));
					root.setAttribute("Counter",String.valueOf(tempCounter-1));
					XMLUtil.writeXMLFile(getTopicDoc_(), topicFileName_);
					Auditor.Log("The topic " + topicId + " was deleted from the forum ", this.getClass());
					return true;
				}
			}

		} catch (DOMException e) {
			return false;
		}
		Auditor.Log("The topic " + topicId + " was Allready deleted from the forum.", this.getClass());
		return false;
	}
	//if there is no such topic id return null
	public Topic getTopicById(int topicId){
		Topic topic = null;
		NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
		for (int i = 0; i < tempNl.getLength(); i++) {
			Node tempNode = tempNl.item(i);
			NamedNodeMap tempNMap = tempNode.getAttributes();
			String id = tempNMap.getNamedItem("ID").getNodeValue();
			if (id.contentEquals(String.valueOf(topicId))){

				String title = tempNMap.getNamedItem("title").getNodeValue();
				String authorName = tempNMap.getNamedItem("authorName").getNodeValue();
				int postCount = Integer.valueOf(tempNMap.getNamedItem("postCount").getNodeValue());
				int viewCount = Integer.valueOf(tempNMap.getNamedItem("viewCount").getNodeValue());
				Date creationDate = null;
				try {
					creationDate = dateFormat_.parse(tempNMap.getNamedItem("creationDate").getNodeValue());
				} catch (DOMException e) {
					e.printStackTrace();
				} catch (ParseException e) {
					e.printStackTrace();
				}
				Vector<Integer> postsIds = new Vector<Integer>();
				//getting the topic's Posts ID :
				for (int j=0;j<tempNode.getChildNodes().item(0).getAttributes().getLength();j++){
					postsIds.add(Integer.valueOf(tempNode.getChildNodes().item(0).getAttributes().item(j).getNodeValue()));
				}

				topic = new Topic(topicId, title, authorName, creationDate,postsIds,postCount,viewCount );
				return topic;
			}
		}
		Auditor.Log("The topic " + topicId + " not in the DataBase.", this.getClass());
		return null;
	}

	//Getters:
	public Vector<Topic> getTopics(){
		Vector<Topic> topics = new Vector<Topic>();
		NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
		for (int i = 0; i < tempNl.getLength(); i++) {
			Node tempNode = tempNl.item(i);
			NamedNodeMap tempNMap = tempNode.getAttributes();
			int id = Integer.valueOf(tempNMap.getNamedItem("ID").getNodeValue());
			String title = tempNMap.getNamedItem("title").getNodeValue();
			String authorName = tempNMap.getNamedItem("authorName").getNodeValue();
			int postCount = Integer.valueOf(tempNMap.getNamedItem("postCount").getNodeValue());
			int viewCount = Integer.valueOf(tempNMap.getNamedItem("viewCount").getNodeValue());
			Date creationDate = null;
			try {
				creationDate = dateFormat_.parse(tempNMap.getNamedItem("creationDate").getNodeValue());
			} catch (DOMException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			}
			Vector<Integer> postsIds = new Vector<Integer>();
			//getting the topic's Posts ID :
			for (int j=0;j<tempNode.getChildNodes().item(0).getAttributes().getLength();j++){
				postsIds.add(Integer.valueOf(tempNode.getChildNodes().item(0).getAttributes().item(j).getNodeValue()));
			}

			Topic tmpPost = new Topic(id, title, authorName, creationDate,postsIds,postCount,viewCount );
			topics.add(tmpPost);
		}
		return topics;
	}
	public void addViewCount(int topicId){
		Topic topic = getTopicById(topicId);
		try {
			NodeList tempNl = getTopicDoc_().getElementsByTagName("Topic");
			for (int i = 0; i < tempNl.getLength(); i++) {
				Node tempNode = tempNl.item(i);
				NamedNodeMap tempNMap = tempNode.getAttributes();
				String id = tempNMap.getNamedItem("ID").getNodeValue();
				if (id.contentEquals(String.valueOf(topicId))) {

					Element newChild = getTopicDoc_().createElement("Topic");
					newChild.setAttribute("ID", String.valueOf(topic.getId_()));
					newChild.setAttribute("title", topic.getTitle_());
					newChild.setAttribute("authorName", String.valueOf(topic.getAuthorName()));
					newChild.setAttribute("creationDate", dateFormat_.format(topic.getCreationDate_()));
					newChild.setAttribute("postCount", String.valueOf(topic.getPostCount()));
					newChild.setAttribute("viewCount", String.valueOf(topic.getViewCount()+1));
					//Modifying the topic's Posts ID :
					Element newPostsID = getTopicDoc_().createElement("PostsIDs");
					for (int j=0;j<topic.getPostVector().size();j++){
						newPostsID.setAttribute("postID"+j, String.valueOf(topic.getPostVector().get(j)));
					}
					newChild.appendChild(newPostsID);
					tempNode.getParentNode().replaceChild(newChild, tempNode);
					Auditor.Log("The topic " + topic.getId_() + " was modified", this.getClass());
					XMLUtil.writeXMLFile(getTopicDoc_(), topicFileName_);
				}
			}

		} catch (DOMException e) {
		}
	}

}
